package com.demo2;

import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

// ========== 4. License验证器 - 嵌入到客户端程序 ==========
class LicenseValidator {
    // 从PublicKeyConstant.java复制过来的公钥
    private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."; // 实际使用时替换为真实公钥
    
    private static final String ALGORITHM = "RSA";
    
    public static boolean validateLicense(String licensePath) {
        try {
            System.out.println("开始验证License文件: " + licensePath);
            
            // 1. 读取license文件
            Properties props = new Properties();
            try (FileInputStream fis = new FileInputStream(licensePath)) {
                props.load(fis);
            }
            
            String licenseDataEncoded = props.getProperty("license_data");
            String signature = props.getProperty("license_signature");
            String version = props.getProperty("license_version");
            
            if (licenseDataEncoded == null || signature == null) {
                System.err.println("License文件格式错误：缺少必要字段");
                return false;
            }
            
            System.out.println("License版本: " + version);
            
            // 2. 解码license数据
            String licenseContent = new String(Base64.getDecoder().decode(licenseDataEncoded), "UTF-8");
            
            // 3. 验证签名
            if (!verifySignature(licenseContent, signature)) {
                System.err.println("License签名验证失败");
                return false;
            }
            
            // 4. 解析并验证license内容
            return parseLicenseAndValidate(licenseContent);
            
        } catch (Exception e) {
            System.err.println("License验证过程中发生错误: " + e.getMessage());
            return false;
        }
    }
    
    // 验证数字签名
    private static boolean verifySignature(String data, String signatureString) {
        try {
            PublicKey publicKey = getPublicKey();
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(publicKey);
            signature.update(data.getBytes(StandardCharsets.UTF_8));
            byte[] signatureBytes = Base64.getUrlDecoder().decode(signatureString);
            return signature.verify(signatureBytes);
            
        } catch (Exception e) {
            System.err.println("签名验证失败: " + e.getMessage());
            e.printStackTrace(); // 添加详细错误信息
            return false;
        }
    }
    
    // 获取公钥对象
    private static PublicKey getPublicKey() throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(PUBLIC_KEY);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(spec);
    }
    
    // 解析并验证license内容
    private static boolean parseLicenseAndValidate(String licenseContent) {
        try {
            Map<String, String> licenseMap = new HashMap<>();
            String[] lines = licenseContent.split("\n");
            
            for (String line : lines) {
                if (line.contains("=")) {
                    String[] parts = line.split("=", 2);
                    licenseMap.put(parts[0].trim(), parts[1].trim());
                }
            }
            
            // 1. 验证过期时间
            String expiryDate = licenseMap.get("expiryDate");
            if (expiryDate != null && !expiryDate.isEmpty()) {
                LocalDateTime expiry = LocalDateTime.parse(expiryDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                if (LocalDateTime.now().isAfter(expiry)) {
                    System.err.println("License已过期: " + expiryDate);
                    return false;
                }
            }
            
            // 2. 验证机器ID
            String licenseMachineId = licenseMap.get("machineId");
            if (licenseMachineId != null && !licenseMachineId.isEmpty() && !licenseMachineId.equals("ANY")) {
                String currentMachineId = MachineIdUtil.getCurrentMachineId();
                if (!licenseMachineId.equals(currentMachineId)) {
                    System.err.println("机器ID不匹配");
                    System.err.println("License绑定机器ID: " + licenseMachineId);
                    System.err.println("当前机器ID: " + currentMachineId);
                    return false;
                }
            }
            
            // 3. 验证产品信息
            String productName = licenseMap.get("productName");
            String productVersion = licenseMap.get("productVersion");
            String maxUsers = licenseMap.get("maxUsers");
            
            System.out.println("\n=== License验证成功 ===");
            System.out.println("客户: " + licenseMap.get("customerName"));
            System.out.println("产品: " + productName + " v" + productVersion);
            System.out.println("到期时间: " + expiryDate);
            System.out.println("最大用户数: " + maxUsers);
            System.out.println("签发时间: " + licenseMap.get("issueDate"));
            
            // 打印功能特性
            System.out.println("授权功能:");
            for (Map.Entry<String, String> entry : licenseMap.entrySet()) {
                if (entry.getKey().startsWith("feature.")) {
                    String featureName = entry.getKey().substring(8); // 去掉"feature."前缀
                    System.out.println("  - " + featureName + ": " + entry.getValue());
                }
            }
            
            return true;
            
        } catch (Exception e) {
            System.err.println("License解析失败: " + e.getMessage());
            return false;
        }
    }
}